package qc.module.ehs.api.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
import qc.common.core.constants.QCAuthConstant;
import qc.common.core.exception.QCPromptException;
import qc.module.ehs.dto.task.*;
import qc.module.ehs.service.EhsTaskInfoService;
import qc.module.platform.dto.uac.UacUserInfoDto;

import javax.servlet.http.HttpServletRequest;

/**
 * EHS 安全任务Controller
 *
 * @author QuCheng Tech
 * @since 2024/11/13
 */
@RestController
@RequestMapping("/task")
public class TaskController {
    
    @Autowired
    private EhsTaskInfoService service;

    @Autowired
    HttpServletRequest request;

    @Autowired
    private RestTemplatePlatform restTemplatePlatform;

    /**
     * 获取安全任务信息
     * 
     * @param id 任务ID
     * @return TaskInfoDto
     * @author QuCheng Tech
     * @since 2024/11/13
     */
    @GetMapping("/info")
    public TaskInfoDto getTaskInfoByParam(@RequestParam String id){
        return service.getTaskInfo(id);
    }

    /**
     * 获取安全任务信息
     *
     * @param id 任务ID
     * @return TaskInfoDto
     * @author QuCheng Tech
     * @since 2024/11/13
     */
    @GetMapping("/info/{id}")
    public TaskInfoDto getTaskInfoByPath(@PathVariable String id){
        return service.getTaskInfo(id);
    }

    /**
     * 新建安全任务
     *
     * @param addDto 新建对象DTO
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/14
     */
    @RequestMapping(value = "/add", method = {RequestMethod.POST})
    public String add(@RequestBody TaskAddOrEditDto addDto) throws QCPromptException {
        HttpHeaders headers = new HttpHeaders();
        headers.add(QCAuthConstant.TOKEN_HEADER_KEY, request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY));
        headers.add(QCAuthConstant.PROJECT_CODE_HEADER_KEY, request.getHeader(QCAuthConstant.PROJECT_CODE_HEADER_KEY));
        //根据token获取用户信息
        UacUserInfoDto userInfo = restTemplatePlatform.getUserInfo(headers);

        return service.add(addDto, userInfo);
    }

    /**
     * 修改安全任务
     *
     * @param editDto 修改对象DTO
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/14
     */
    @RequestMapping(value = "/update", method = {RequestMethod.POST, RequestMethod.PUT})
    public String update(@RequestBody TaskAddOrEditDto editDto) throws QCPromptException {
        return service.update(editDto);
    }

    /***
     * 任务信息预览
     *
     * @param dto 任务信息 
     * @return qc.module.ehs.dto.task.TaskPreviewResultDto
     * @author QuCheng Tech
     * @since 2025/1/16
     */
    @RequestMapping(value = "/preview", method = {RequestMethod.POST, RequestMethod.PUT})
    public TaskPreviewResultDto preview(@RequestBody TaskAddOrEditDto dto) {
        return service.preview(dto);
    }

    /**
     * 删除安全任务
     * 仅支持对未派单的任务进行删除；删除采用物理删除，同时删除任务分组表和任务项表中的记录；
     *
     * @param id 任务ID
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/14
     */
    @DeleteMapping("/delete")
    public String deleteByParam(@RequestParam String id){
        return service.delete(id);
    }

    /**
     * 删除安全任务
     * 仅支持对未派单的任务进行删除；删除采用物理删除，同时删除任务分组表和任务项表中的记录；
     *
     * @param id 任务ID
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/14
     */
    @DeleteMapping("/delete/{id}")
    public String deleteByPath(@PathVariable String id){
        return service.delete(id);
    }

    /**
     * 获取安全任务分组关联的对象
     * 
     * @param id 任务ID
     * @return TaskGroupObjectsDto
     * @author QuCheng Tech
     * @since 2024/11/14
     */
    @GetMapping("/groupobjects")
    public TaskGroupObjectsDto getTaskGroupObjectsByParam(@RequestParam String id){
        return service.getTaskGroupObjects(id);
    }

    /**
     * 获取安全任务分组关联的对象
     *
     * @param id 任务ID
     * @return TaskGroupObjectsDto
     * @author QuCheng Tech
     * @since 2024/11/14
     */
    @GetMapping("/groupobjects/{id}")
    public TaskGroupObjectsDto getTaskGroupObjectsByPath(@PathVariable String id){
        return service.getTaskGroupObjects(id);
    }

    /**
     * 设置任务分组
     * 
     * 根据任务中的对象类型，选择任务关联的对象集合；
     * 不管任务是否派单均能进行该操作，要求任务的执行完成为false并且终止/取消为false；
     * 该操作不影响已执行的分组和任务项；
     * 设置分组的对象与已有的分组中的对象可能有3种情况：已存在相同、本次新增加、本次删除原有；
     * 已存在相同：不需要对分组信息进行任何操作；
     * 本次新增加：在分组中添加相应信息，任务项的执行周期从添加的当前时间开始计算；
     * 本次删除原有：在分组中对本次删除的分组设置终止/取消为true，同时对任务项中设置终止/取消为true；
     * 
     * @param dto
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/14
     */
    @RequestMapping(value = "/groups",method = {RequestMethod.POST})
    public String setTaskGroups(@RequestBody TaskSetGroupObjectsDto dto){
        return service.setTaskGroups(dto);
    }

    /**
     * 对指定的安全任务进行派单
     * 
     * 对指定的安全任务进行派单操作；派单后不能取消，只能终止任务；对已经派单或结束（终止/完成）的任务不能进行派单；
     * 对任务进行派单时才根据任务分组生成任务项，任务项中均为已经派单的任务；根据任务项中的计划执行时间确定在不同时间段内（本月、本年）内的任务；
     * 
     * @param dto 任务派单DTO
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/15
     */
    @RequestMapping(value = "/dispatch",method = {RequestMethod.POST})
    public String dispatchByParam(@RequestBody TaskDispatchDto dto) throws QCPromptException {
        return service.dispatch(dto);
    }

    /**
     * 对指定的安全任务设置为完成
     *
     * 设置总任务为完成状态；
     * 需要判断任务分组的状态，每个分组的状态必须是执行完成为true或终止/取消为true；即要求每个分组都执行完、或者被终止/取消（不需要执行）；
     *
     * @param id 任务ID
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/15
     */
    @RequestMapping(value = "/finish",method = {RequestMethod.POST})
    public String finishByParam(@RequestParam String id){
        return service.finish(id);
    }

    /**
     * 对指定的安全任务设置为完成
     *
     * 设置总任务为完成状态；
     * 需要判断任务分组的状态，每个分组的状态必须是执行完成为true或终止/取消为true；即要求每个分组都执行完、或者被终止/取消（不需要执行）；
     *
     * @param id 任务ID
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/15
     */
    @RequestMapping(value = "/finish/{id}",method = {RequestMethod.POST})
    public String finishByPath(@PathVariable String id){
        return service.finish(id);
    }

    /**
     * 对指定的安全任务设置为终止
     *
     * 要求同时满足以下条件才能进行终止：任务的派单状态为true，任务的执行完成为false，任务的终止/取消为false；
     * 任务的派单状态为false时，提示任务未派单，如不需要该任务可以直接删除；
     * 任务的执行完成为true时，提示任务已经执行完成，无需进行终止；
     * 任务的终止/取消为true时，提示任务已终止/取消，无需重复操作；
     * 设置任务为终止时，需要同步对任务分组和任务项中执行完成为false且终止/取消为false的设置终止/取消为true；
     *
     * @param id 任务ID
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/15
     */
    @RequestMapping(value = "/end",method = {RequestMethod.POST})
    public String endByParam(@RequestParam String id){
        return service.end(id);
    }

    /**
     * 对指定的安全任务设置为终止
     *
     * 要求同时满足以下条件才能进行终止：任务的派单状态为true，任务的执行完成为false，任务的终止/取消为false；
     * 任务的派单状态为false时，提示任务未派单，如不需要该任务可以直接删除；
     * 任务的执行完成为true时，提示任务已经执行完成，无需进行终止；
     * 任务的终止/取消为true时，提示任务已终止/取消，无需重复操作；
     * 设置任务为终止时，需要同步对任务分组和任务项中执行完成为false且终止/取消为false的设置终止/取消为true；
     *
     * @param id 任务ID
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/15
     */
    @RequestMapping(value = "/end/{id}",method = {RequestMethod.POST})
    public String endByPath(@PathVariable String id){
        return service.end(id);
    }

    /**
     * 对指定的安全任务设置为继续
     *
     * 对已经终止的任务设置为继续；要求终止/取消为true的才能进行继续操作；
     * 设置任务为继续时，需要同步对任务分组和任务项中终止/取消为true的设置终止/取消为false；
     * 对执行完成为true的不进行修改，包含任务、任务分组和任务项均不进行修改；
     *
     * @param id 任务ID
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/15
     */
    @RequestMapping(value = "/continue",method = {RequestMethod.POST})
    public String continueByParam(@RequestParam String id){
        return service.setContinue(id);
    }

    /**
     * 对指定的安全任务设置为继续
     *
     * 对已经终止的任务设置为继续；要求终止/取消为true的才能进行继续操作；
     * 设置任务为继续时，需要同步对任务分组和任务项中终止/取消为true的设置终止/取消为false；
     * 对执行完成为true的不进行修改，包含任务、任务分组和任务项均不进行修改；
     *
     * @param id 任务ID
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/15
     */
    @RequestMapping(value = "/continue/{id}",method = {RequestMethod.POST})
    public String continueByPath(@PathVariable String id){
        return service.setContinue(id);
    }
}
